/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.velocityme.session;

import com.velocityme.entity.ChangeDelta;
import com.velocityme.entity.Role;
import com.velocityme.enums.ChangeDeltaItemType;
import com.velocityme.enums.ChangeDeltaType;
import com.velocityme.enums.Permission;
import com.velocityme.utility.PermissionCache;
import java.util.Collection;
import java.util.HashSet;
import java.util.Set;
import javax.ejb.EJB;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

/**
 *
 * @author rcrida
 */
@Stateless
public class RoleBean implements RoleLocal {

    @PersistenceContext
    private EntityManager em;

    @EJB
    private NodeLocal nodeBean;

    public Collection<Role> findAllRoles(KeyLocal key) {
        key.validateKey();
        return em.createNamedQuery("findAllRoles").getResultList();
    }

    public Role findRole(KeyLocal key, Long roleId) {
        Role role = em.find(Role.class, roleId);
        key.assertHasPermission(role, Permission.NODE_VIEW);
        return role;
    }

    public Role createRole(KeyLocal key, Role role) {
        key.assertHasPermission(role.getParentNode(), Permission.ROLE_CREATE);
        ChangeDelta changeDelta = role.addChangeDelta(ChangeDeltaType.CREATE, key.getUser());
        nodeBean.logCreate(role, changeDelta);
        changeDelta.addItem(ChangeDeltaItemType.RECURSIVE, Boolean.toString(role.isRecursive()));
        for (Permission permission: role.getPermissions()) {
            changeDelta.addItem(ChangeDeltaItemType.ADD_PERMISSION, permission.toString());
        }
        em.persist(role);
        em.persist(changeDelta);
        return role;
    }

    public void editRole(KeyLocal key, Role role) {
        Role current = em.find(Role.class, role.getId());
        key.assertHasPermission(role, Permission.ROLE_EDIT);
        ChangeDelta changeDelta = role.addChangeDelta(ChangeDeltaType.EDIT, key.getUser());
        nodeBean.logEdit(role, current, changeDelta);
        if (role.isRecursive() != current.isRecursive()) {
            changeDelta.addItem(ChangeDeltaItemType.RECURSIVE, Boolean.toString(role.isRecursive()));
        }
        Set<Permission> permissionsBefore = current.getPermissions();
        Set<Permission> permissionsDisabled = new HashSet<Permission>(permissionsBefore);
        permissionsDisabled.removeAll(role.getPermissions());
        Set<Permission> permissionsEnabled = new HashSet(role.getPermissions());
        permissionsEnabled.removeAll(permissionsBefore);
        for (Permission permission: permissionsDisabled) {
            changeDelta.addItem(ChangeDeltaItemType.REMOVE_PERMISSION, permission.toString());
        }
        for (Permission permission: permissionsEnabled) {
            changeDelta.addItem(ChangeDeltaItemType.ADD_PERMISSION, permission.toString());
        }
        em.persist(changeDelta);
        em.merge(role);
        // clear the permission cache
        PermissionCache.getInstance().clear();
    }

    // Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Business Method" or "Web Service > Add Operation")
 
}
